home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 4_2005-2006.ISO / data / Zips / VB6_CLASSE196928212006.psc / Advance Registry.cls < prev    next >
Text File  |  2006-01-15  |  41KB  |  1,001 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "cAdvanceRegistry"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. ' --------------------------------------------------------------------------------
  17. ' Name:     cAdvanceRegistry class
  18. ' Author:   Noel A. Dacara (noeldacara@hotmail.com)
  19. ' Date:     2 June 2005
  20. '
  21. ' You can freely use and distribute this file with or without permission provided
  22. ' that credits herein are kept unmodified and having acknowledgements is observed.
  23. '
  24. ' Caution:  Incorrectly editing the registry may severely damage your system.
  25. '           Before using this class, backup any valued data on your computer.
  26. '
  27. ' Notes:    To access Remote registry for Windows NT 4.0, 2000, XP, or 2003, run
  28. '           the program from an account that has permission to that remote system.
  29. '
  30. '           Be careful in using DeleteTree function. Backup registry for assurance.
  31. '           Author will not be held liable for any damages while using the class.
  32. '
  33. '           Binary typed registry data are returned as an array of ascii numbers.
  34. '           Binary in unicode format can be usually read as normal strings.
  35. '
  36. ' Sample:   Dim KeyArray() As String
  37. '           If REG.EnumerateKeys(KeyArray, HKEY_LOCAL_MACHINE, "Software") Then
  38. '               For i = 0 To UBound(KeyArray)
  39. '                   Debug.Print KeyArray(i)
  40. '               Next
  41. '           End If
  42. '
  43. ' Inquiries or comments regarding my works and whatsoever are greatly appreciated.
  44. ' --------------------------------------------------------------------------------
  45.  
  46. ' API declarations
  47. Private Declare Function ExpandEnvironmentStrings Lib "kernel32.dll" Alias "ExpandEnvironmentStringsA" (ByVal lpSrc As String, ByVal lpDst As String, ByVal nSize As Long) As Long
  48. Private Declare Function GetQueueStatus Lib "user32.dll" (ByVal fuFlags As Long) As Long
  49. Private Declare Function lstrlen Lib "kernel32.dll" Alias "lstrlenA" (ByVal lpString As String) As Long
  50. Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
  51. Private Declare Function RegConnectRegistry Lib "advapi32.dll" Alias "RegConnectRegistryA" (ByVal lpMachineName As String, ByVal hKey As Long, ByRef phkResult As Long) As Long
  52. Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, ByVal lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long, ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, ByRef phkResult As Long, ByRef lpdwDisposition As Long) As Long
  53. Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
  54. Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
  55. Private Declare Function RegEnumKey Lib "advapi32.dll" Alias "RegEnumKeyA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, ByVal cbName As Long) As Long
  56. Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, ByRef phkResult As Long) As Long
  57. Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, ByRef lpType As Long, ByRef lpData As Any, ByRef lpcbData As Long) As Long
  58. Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Any, ByVal cbData As Long) As Long
  59. Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
  60.  
  61. ' Modified API declarations
  62. Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Long, ByRef Source As Long, ByVal Length As Long)
  63. Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, ByRef lpcbValueName As Long, ByVal lpReserved As Long, ByVal lpType As Long, ByVal lpData As Byte, ByVal lpcbData As Long) As Long
  64. Private Declare Function RegQueryInfoKey Lib "advapi32.dll" Alias "RegQueryInfoKeyA" (ByVal hKey As Long, ByVal lpClass As String, ByRef lpcbClass As Long, ByVal lpReserved As Long, ByRef lpcSubKeys As Long, ByRef lpcbMaxSubKeyLen As Long, ByRef lpcbMaxClassLen As Long, ByRef lpcValues As Long, ByRef lpcbMaxValueNameLen As Long, ByRef lpcbMaxValueLen As Long, ByRef lpcbSecurityDescriptor As Long, ByRef lpftLastWriteTime As FILETIME) As Long
  65. Private Declare Function RegQueryValueExByte Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal lKey As Long, ByVal lpValueName As String, ByVal lReserved As Long, ByRef lpType As Long, ByRef lpData As Byte, ByRef lpcbData As Long) As Long
  66. Private Declare Function RegQueryValueExDouble Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal lKey As Long, ByVal lpValueName As String, ByVal lReserved As Long, ByRef lpType As Long, ByRef lpData As Double, ByRef lpcbData As Long) As Long
  67. Private Declare Function RegQueryValueExLong Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal lKey As Long, ByVal lpValueName As String, ByVal lReserved As Long, ByRef lpType As Long, ByRef lpData As Long, ByRef lpcbData As Long) As Long
  68. Private Declare Function RegQueryValueExString Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal lKey As Long, ByVal lpValueName As String, ByVal lReserved As Long, ByRef lpType As Long, ByVal lpData As String, ByRef lpcbData As Long) As Long
  69. Private Declare Function RegSetValueExByte Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Byte, ByVal cbData As Long) As Long
  70. Private Declare Function RegSetValueExDouble Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Double, ByVal cbData As Long) As Long
  71. Private Declare Function RegSetValueExLong Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Long, ByVal cbData As Long) As Long
  72. Private Declare Function RegSetValueExString Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long
  73.  
  74. ' API Constants
  75. Private Const QS_HOTKEY                 As Long = &H80
  76. Private Const QS_KEY                    As Long = &H1
  77. Private Const QS_MOUSEBUTTON            As Long = &H4
  78. Private Const QS_MOUSEMOVE              As Long = &H2
  79. Private Const QS_MOUSE                  As Long = (QS_MOUSEMOVE Or QS_MOUSEBUTTON)
  80. Private Const QS_INPUT                  As Long = (QS_MOUSE Or QS_KEY)
  81. Private Const QS_PAINT                  As Long = &H20
  82. Private Const QS_POSTMESSAGE            As Long = &H8
  83. Private Const QS_TIMER                  As Long = &H10
  84. Private Const QS_ALLEVENTS              As Long = (QS_INPUT Or QS_POSTMESSAGE Or QS_TIMER Or QS_PAINT Or QS_HOTKEY)
  85.  
  86. ' Registry security option constants
  87. Private Const KEY_CREATE_LINK           As Long = &H20
  88. Private Const KEY_CREATE_SUB_KEY        As Long = &H4
  89. Private Const KEY_ENUMERATE_SUB_KEYS    As Long = &H8
  90. Private Const KEY_NOTIFY                As Long = &H10
  91. Private Const KEY_QUERY_VALUE           As Long = &H1
  92. Private Const KEY_SET_VALUE             As Long = &H2
  93. Private Const STANDARD_RIGHTS_ALL       As Long = &H1F0000
  94. Private Const SYNCHRONIZE               As Long = &H100000
  95. Private Const KEY_ALL_ACCESS            As Long = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
  96.  
  97. ' Registry create type values
  98. Private Const REG_OPTION_NON_VOLATILE   As Long = 0 ' Key is preserved on system reboot
  99. Private Const REG_OPTION_RESERVED       As Long = 0 ' Parameter is reserved for future use
  100.  
  101. ' Registry create/open disposition
  102. Private Const REG_CREATED_NEW_KEY   As Long = &H1   ' New registry key was created
  103. Private Const MAX_CLASS_NAME        As Long = 255
  104.  
  105. ' Registry return constants
  106. Private Const ERROR_ACCESS_DENIED   As Long = 5&    ' Access to registry key was denied
  107. Private Const ERROR_MORE_DATA       As Long = 234   ' More data is available
  108. Private Const ERROR_NO_MORE_ITEMS   As Long = 259&  ' No data is available
  109. Private Const ERROR_SUCCESS         As Long = 0&    ' Operation was completed successfully
  110.  
  111. ' API types
  112. Private Type FILETIME
  113.     dwLowDateTime   As Long
  114.     dwHighDateTime  As Long
  115. End Type
  116.  
  117. Private Type SECURITY_ATTRIBUTES
  118.     nLength                 As Long
  119.     lpSecurityDescriptor    As Long
  120.     bInheritHandle          As Long
  121. End Type
  122.  
  123. ' Public enums
  124. Public Enum ERegistryRoots
  125.     HKEY_CLASSES_ROOT = &H80000000  ' Contains file association mappings
  126.     HKEY_CURRENT_USER = &H80000001  ' Contains information about the current user
  127.     HKEY_LOCAL_MACHINE = &H80000002 ' Contains computer specific information
  128.     HKEY_USERS = &H80000003         ' Contains individual preferences for each users
  129. End Enum
  130.  
  131. #If False Then
  132.     ' Trick to preserve casing of these variables when used in VB IDE
  133.     Private HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS
  134. #End If
  135.  
  136. 'Common registry data types
  137. Public Enum ERegistryDataTypes
  138.     REG_BINARY = 3                  ' Binary data in any form
  139.     REG_DWORD = 4                   ' 32-bit number
  140.     REG_DWORD_BIG_ENDIAN = 5        ' 32-bit number in big-endian format
  141.     REG_DWORD_LITTLE_ENDIAN = 4     ' 32-bit number in little-endian format
  142.     REG_EXPAND_SZ = 2               ' Contains unexpanded references to environment variables (Ex. %SystemRoot%=C:\Windows)
  143.     REG_MULTI_SZ = 7                ' String that contain lists or multiple values
  144.     REG_QWORD = 11                  ' 64-bit number
  145.     REG_QWORD_LITTLE_ENDIAN = 11    ' 64-bit number in little-endian format
  146.     REG_SZ = 1                      ' Standard string
  147.     
  148.     ' Read-only purpose data types
  149.     REG_FULL_RESOURCE_DESCRIPTOR = 9    '
  150.     REG_LINK = 6                        ' Unicode symbolic link
  151.     REG_NONE = 0                        ' No defined value type
  152.     REG_RESOURCE_LIST = 8               ' A device-driver resource list
  153.     REG_RESOURCE_REQUIREMENTS_LIST = 10 '
  154. End Enum
  155.  
  156. #If False Then
  157.     ' Trick to preserve casing of these variables when used in VB IDE
  158.     Private REG_BINARY, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_DWORD_LITTLE_ENDIAN
  159.     Private REG_EXPAND_SZ, REG_MULTI_SZ, REG_QWORD, REG_QWORD_LITTLE_ENDIAN
  160.     Private REG_SZ, REG_FULL_RESOURCE_DESCRIPTOR, REG_LINK, REG_NONE
  161.     Private REG_RESOURCE_LIST, REG_RESOURCE_REQUIREMENTS_LIST
  162. #End If
  163.  
  164. ' Variable declarations
  165. Private m_bRemoteConnection As Boolean
  166. Private m_eClassRoot        As ERegistryRoots
  167. Private m_eDataType         As ERegistryDataTypes
  168. Private m_eRemoteClassRoot  As ERegistryRoots
  169. Private m_lRemoteKey        As Long
  170. Private m_sKey              As String
  171. Private m_sMachineName      As String
  172. Private m_sValueName        As String
  173. Private m_vDefault          As Variant
  174.  
  175. ' //-- Properties --//
  176.  
  177. Public Property Get ClassRoot() As ERegistryRoots
  178. Attribute ClassRoot.VB_Description = "Returns/sets a value to determine the registry key root type used."
  179. 'Returns/sets a value to determine the registry key root type used.
  180.     ClassRoot = m_eClassRoot
  181. End Property
  182.  
  183. Public Property Let ClassRoot(Value As ERegistryRoots)
  184.     If (Value = 0) Then
  185.         Err.Raise -1, , "Invalid registry class root value."
  186.         Exit Property
  187.     End If
  188.     
  189.     m_eClassRoot = Value
  190. End Property
  191.  
  192. Public Property Get DataType() As ERegistryDataTypes
  193. Attribute DataType.VB_Description = "Returns a value to determine the data type used or set the data type to be used."
  194. 'Returns a value to determine the data type used or set the data type to be used.
  195.     DataType = m_eDataType
  196. End Property
  197.  
  198. Public Property Let DataType(Value As ERegistryDataTypes)
  199.     m_eDataType = Value
  200. End Property
  201.  
  202. Public Property Get Default() As Variant
  203. Attribute Default.VB_Description = "Returns/sets the default registry value to be used incase of problems."
  204. 'Returns/sets the default registry value to be used incase of problems.
  205.     Default = m_vDefault
  206. End Property
  207.  
  208. Public Property Let Default(Value As Variant)
  209.     m_vDefault = Value
  210. End Property
  211.  
  212. Public Property Get Key() As String
  213. Attribute Key.VB_Description = "Returns/sets a value to determines the registry key/section to be used."
  214. 'Returns/sets a value to determines the registry key/section to be used.
  215.     Key = m_sKey
  216. End Property
  217.  
  218. Public Property Let Key(Value As String)
  219.     m_sKey = Value
  220. End Property
  221.  
  222. Public Property Get MachineName() As String
  223. Attribute MachineName.VB_Description = "Returns/sets the name of computer where to establish a remote registry connection."
  224. 'Returns/sets the name of computer where to establish a remote registry connection.
  225.     MachineName = m_sMachineName
  226. End Property
  227.  
  228. Public Property Let MachineName(Value As String)
  229.     ValidateMachineName Value ' make sure name is in the proper format
  230.     m_sMachineName = Value
  231. End Property
  232.  
  233. Public Property Get Value() As Variant
  234. Attribute Value.VB_Description = "Returns/sets the value of a registry data."
  235. 'Returns/sets the value of a registry data.
  236.     Value = Me.ValueEx
  237. End Property
  238.  
  239. Public Property Let Value(Value As Variant)
  240.     Me.ValueEx = Value
  241. End Property
  242.  
  243. Public Property Get ValueEx( _
  244.         Optional ClassRoot, _
  245.         Optional Key, _
  246.         Optional ValueName) As Variant
  247. Attribute ValueEx.VB_Description = "Returns/sets the value of the specified registry data."
  248. 'Returns/sets the value of the specified registry data.
  249.     If (Not IsMissing(ClassRoot)) Then
  250.         m_eClassRoot = ClassRoot
  251.     End If
  252.     
  253.     If (Not IsMissing(Key)) Then
  254.         m_sKey = Key
  255.     End If
  256.     
  257.     If (Not IsMissing(ValueName)) Then
  258.         m_sValueName = ValueName
  259.     End If
  260.     
  261.     Dim p_bBinary() As Byte
  262.     Dim p_lDword    As Long
  263.     Dim p_lKey      As Long
  264.     Dim p_lRet      As Long
  265.     Dim p_lDataLen  As Long
  266.     Dim p_lDataType As Long
  267.     Dim p_sBuffer   As String
  268.     
  269.     If (m_bRemoteConnection) Then
  270.         ClassRoot = m_lRemoteKey
  271.     End If
  272.     
  273.     p_lRet = RegOpenKeyEx(m_eClassRoot, m_sKey, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, p_lKey)
  274.     p_lRet = RegQueryValueExLong(p_lKey, m_sValueName, REG_OPTION_RESERVED, p_lDataType, 0&, p_lDataLen)
  275.     
  276.     If (p_lRet) And (p_lRet <> ERROR_MORE_DATA) Then
  277.         ValueEx = m_vDefault
  278.         Exit Property
  279.     End If
  280.     
  281.     m_eDataType = p_lDataType
  282.     
  283.     Select Case p_lDataType
  284.         Case REG_SZ, REG_MULTI_SZ, REG_EXPAND_SZ
  285.             p_sBuffer = String$(p_lDataLen, 0)
  286.             p_lRet = RegQueryValueExString(p_lKey, m_sValueName, REG_OPTION_RESERVED, p_lDataType, p_sBuffer, p_lDataLen)
  287.             
  288.             If (p_lDataType = REG_EXPAND_SZ) Then
  289.                 ValueEx = ExpandEnvironmentString(p_sBuffer) ' Expand %VARIABLES%
  290.             Else
  291.                 If (p_lDataLen > 0) Then
  292.                     ValueEx = Left$(p_sBuffer, p_lDataLen - 1)
  293.                 End If
  294.             End If
  295.             
  296.         Case REG_DWORD, REG_DWORD_LITTLE_ENDIAN, REG_DWORD_BIG_ENDIAN
  297.             p_lRet = RegQueryValueExLong(p_lKey, m_sValueName, REG_OPTION_RESERVED, p_lDataType, p_lDword, p_lDataLen)
  298.             
  299.             If (p_lDataType = REG_DWORD) Then
  300.                 ValueEx = CLng(p_lDword)
  301.             Else
  302.                 ValueEx = GetBigEndianValue(p_lDword) ' REG_DWORD_BIG_ENDIAN
  303.             End If
  304.             
  305.         Case REG_QWORD, REG_QWORD_LITTLE_ENDIAN
  306.             Dim p_dQword As Double
  307.             
  308.             p_lRet = RegQueryValueExDouble(p_lKey, m_sValueName, REG_OPTION_RESERVED, p_lDataType, p_dQword, p_lDataLen)
  309.             ValueEx = CDbl(p_dQword)
  310.             
  311.         Case Else
  312.             If (p_lDataLen > 0) Then
  313.                 ReDim p_bBinary(p_lDataLen - 1) ' without the terminating null character
  314.                 
  315.                 p_lRet = RegQueryValueExByte(p_lKey, m_sValueName, REG_OPTION_RESERVED, p_lDataType, p_bBinary(0), p_lDataLen)
  316.             End If
  317.             
  318.             ValueEx = p_bBinary ' return as an array of characters
  319.     End Select
  320.     
  321.     RegCloseKey p_lKey
  322. End Property
  323.  
  324. Public Property Let ValueEx( _
  325.         Optional ClassRoot, _
  326.         Optional Key, _
  327.         Optional ValueName, _
  328.         Value As Variant)
  329.     If (Not IsMissing(ClassRoot)) Then
  330.         m_eClassRoot = ClassRoot
  331.     End If
  332.     
  333.     If (Not IsMissing(Key)) Then
  334.         m_sKey = Key
  335.     End If
  336.     
  337.     If (Not IsMissing(ValueName)) Then
  338.         m_sValueName = ValueName
  339.     End If
  340.     
  341.     Dim p_bByte()       As Byte
  342.     Dim p_dQword        As Double
  343.     Dim p_lDword        As Long
  344.     Dim p_lKey          As Long
  345.     Dim p_lLen          As Long
  346.     Dim p_lRet          As Long
  347.     Dim p_sString       As String
  348.     Dim p_tSecAttrib    As SECURITY_ATTRIBUTES
  349.     
  350.     If (m_bRemoteConnection) Then
  351.         m_eClassRoot = m_lRemoteKey
  352.     End If
  353.     
  354.     p_lRet = RegCreateKeyEx(m_eClassRoot, m_sKey, REG_OPTION_RESERVED, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, p_tSecAttrib, p_lKey, 0&)
  355.     
  356.     If (p_lRet = ERROR_SUCCESS) Then
  357.         Select Case m_eDataType
  358.             Case REG_BINARY
  359.                 ' Can also accept strings
  360.                 If (VarType(Value) = (vbArray + vbByte) Or vbString) Then
  361.                     p_bByte = Value
  362.                 Else
  363.                     Err.Raise m_eDataType, , "Cannot set the specified value in the registry using the defined data type."
  364.                 End If
  365.                 
  366.                 p_lLen = UBound(p_bByte) - LBound(p_bByte) + 1
  367.                 p_lRet = RegSetValueExByte(p_lKey, m_sValueName, REG_OPTION_RESERVED, m_eDataType, p_bByte(0), p_lLen)
  368.                 
  369.             Case REG_SZ, REG_MULTI_SZ, REG_EXPAND_SZ
  370.                 p_sString = Value
  371.                 
  372.                 If (m_eDataType = REG_MULTI_SZ) Then
  373.                     ' Replace all linefeeds with null characters
  374.                     p_sString = Replace$(p_sString, vbNewLine, vbNullChar)
  375.                     
  376.                     ' Windows« Registry Editor does not allow REG_MULTI_SZ
  377.                     ' typed data to contain empty lines and so as we...
  378.                     While InStr(1, p_sString, String$(2, vbNullChar)) > 0
  379.                         p_sString = Replace$(p_sString, String$(2, vbNullChar), vbNullChar)
  380.                     Wend
  381.                     
  382.                     ' REG_MULTI_SZ typed data is terminated by two null characters
  383.                     If Right$(p_sString, 1) = vbNullChar Then
  384.                         p_sString = p_sString & vbNullChar
  385.                     End If
  386.                 End If
  387.                 
  388.                 p_sString = p_sString & vbNullChar ' Terminate with null character
  389.                 p_lLen = Len(p_sString)
  390.                 
  391.                 p_lRet = RegSetValueExString(p_lKey, m_sValueName, REG_OPTION_RESERVED, m_eDataType, p_sString, p_lLen)
  392.                 
  393.             Case REG_DWORD, 5 ' REG_DWORD_LITTLE_ENDIAN, REG_DWORD_BIG_ENDIAN
  394.                 If (VarType(Value) = vbInteger Or vbLong) Then
  395.                     p_lDword = CLng(Value)
  396.                     p_lLen = 4 ' 32-bits
  397.                     
  398.                     p_lRet = RegSetValueExLong(p_lKey, m_sValueName, REG_OPTION_RESERVED, m_eDataType, p_lDword, p_lLen)
  399.                 Else
  400.                     Err.Raise m_eDataType, , "Cannot set the specified value in the registry using the defined data type."
  401.                 End If
  402.                 
  403.             Case REG_QWORD ' REG_QWORD_LITTLE_ENDIAN
  404.                 If (VarType(Value) = vbInteger Or vbLong Or vbDouble) Then
  405.                     p_dQword = CDbl(Value)
  406.                     p_lLen = 8 ' 64-bits
  407.                     
  408.                     p_lRet = RegSetValueExDouble(p_lKey, m_sValueName, REG_OPTION_RESERVED, m_eDataType, p_dQword, p_lLen)
  409.                 Else
  410.                     Err.Raise m_eDataType, , "Cannot set the specified value in the registry using the defined data type."
  411.                 End If
  412.                 
  413.             Case Else
  414.                 Err.Raise m_eDataType, , "The specified data type is either invalid or not supported for write purpose."
  415.         End Select
  416.         
  417.         RegCloseKey p_lKey
  418.     Else
  419.         Err.Raise ClassRoot, , "Unable to open/create registry key: '" & m_sKey & "' for setting new value of '" & m_sValueName & "' to '" & Value & "'"
  420.     End If
  421. End Property
  422.  
  423. Public Property Get ValueName() As String
  424. Attribute ValueName.VB_Description = "Returns/sets a name to identify a particular registry data."
  425. 'Returns/sets a name to identify a particular registry data.
  426.     ValueName = m_sValueName
  427. End Property
  428.  
  429. Public Property Let ValueName(Value As String)
  430.     m_sValueName = Value
  431. End Property
  432.  
  433. ' //-- Public procedures --//
  434.  
  435. Public Function CreateKey(Optional ClassRoot, Optional Key) As Boolean
  436. Attribute CreateKey.VB_Description = "Creates a new registry key from a specified path of a registry root."
  437. 'Creates a new registry key from a specified path of a registry root.
  438.     If (Not IsMissing(ClassRoot)) Then
  439.         m_eClassRoot = ClassRoot
  440.     End If
  441.     
  442.     If (Not IsMissing(Key)) Then
  443.         m_sKey = Key
  444.     End If
  445.     
  446.     Dim p_lKey          As Long
  447.     Dim p_lRet          As Long
  448.     Dim p_tSecAttrib    As SECURITY_ATTRIBUTES
  449.     
  450.     If (m_bRemoteConnection) Then
  451.         m_eClassRoot = m_lRemoteKey
  452.     End If
  453.     
  454.     p_lRet = RegCreateKeyEx(m_eClassRoot, m_sKey, REG_OPTION_RESERVED, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, p_tSecAttrib, p_lKey, 0&)
  455.     
  456.     If (p_lRet = ERROR_SUCCESS) Then
  457.         CreateKey = True
  458.         RegCloseKey p_lKey
  459.     Else
  460.         Err.Raise ClassRoot, , "Unable to create registry key: '" & m_sKey & "'"
  461.     End If
  462. End Function
  463.  
  464. Public Function DeleteAllData(Optional ClassRoot, Optional Key) As Boolean
  465. Attribute DeleteAllData.VB_Description = "Remove and clear all data of the specified registry key."
  466. 'Remove and clear all data of the specified registry key.
  467.     If (Not IsMissing(ClassRoot)) Then
  468.         m_eClassRoot = ClassRoot
  469.     End If
  470.     
  471.     If (Not IsMissing(Key)) Then
  472.         m_sKey = Key
  473.     End If
  474.     
  475.     Dim p_sDataArray()  As String
  476.     Dim p_lCtr          As Long
  477.     
  478.     If (EnumerateData(p_sDataArray, m_eClassRoot, m_sKey)) Then
  479.         For p_lCtr = LBound(p_sDataArray) To UBound(p_sDataArray)
  480.             DeleteData m_eClassRoot, m_sKey, p_sDataArray(p_lCtr)
  481.         Next
  482.         
  483.         DeleteAllData = True
  484.     End If
  485. End Function
  486.  
  487. Public Function DeleteData(Optional ClassRoot, Optional Key, Optional ValueName) As Boolean
  488. Attribute DeleteData.VB_Description = "Removes the specified data on a particular registry key and class root."
  489. 'Removes the specified data on a particular registry key and class root.
  490.     If (Not IsMissing(ClassRoot)) Then
  491.         m_eClassRoot = ClassRoot
  492.     End If
  493.     
  494.     If (Not IsMissing(Key)) Then
  495.         m_sKey = Key
  496.     End If
  497.     
  498.     If (Not IsMissing(ValueName)) Then
  499.         m_sValueName = ValueName
  500.     End If
  501.     
  502.     Dim p_lKey As Long
  503.     Dim p_lRet As Long
  504.     
  505.     If (m_bRemoteConnection) Then
  506.         m_eClassRoot = m_lRemoteKey
  507.     End If
  508.     
  509.     p_lRet = RegOpenKeyEx(m_eClassRoot, m_sKey, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, p_lKey)
  510.     
  511.     If (p_lRet = ERROR_SUCCESS) Then
  512.         p_lRet = RegDeleteValue(p_lKey, m_sValueName)
  513.         
  514.         If (p_lRet = ERROR_SUCCESS) Then
  515.             DeleteData = True
  516.         End If
  517.         
  518.         RegCloseKey p_lKey
  519.     Else
  520.         Err.Raise ClassRoot, , "Unable to open registry key '" & m_sKey & "' for delete access."
  521.     End If
  522. End Function
  523.  
  524. Public Function DeleteKey(Optional ClassRoot, Optional Key) As Boolean
  525. Attribute DeleteKey.VB_Description = "Removes the specified key on a particular class root in the registry."
  526. 'Removes the specified key on a particular class root in the registry.
  527.     If (Not IsMissing(ClassRoot)) Then
  528.         m_eClassRoot = ClassRoot
  529.     End If
  530.     
  531.     If (Not IsMissing(Key)) Then
  532.         m_sKey = Key
  533.     End If
  534.     
  535.     Dim p_lKey          As Long
  536.     Dim p_lRet          As Long
  537.     Dim p_sChildKey     As String
  538.     Dim p_sParentKey    As String
  539.     
  540.     If (m_bRemoteConnection) Then
  541.         ClassRoot = m_lRemoteKey
  542.     End If
  543.     
  544.     p_sParentKey = GetParentKey(m_sKey) ' Get parent key
  545.     p_lRet = RegOpenKeyEx(m_eClassRoot, p_sParentKey, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, p_lKey)
  546.     
  547.     If (p_lRet = ERROR_SUCCESS) Then
  548.         If (Len(p_sParentKey) = 0) Then
  549.             p_sParentKey = m_sKey
  550.         Else
  551.             p_sChildKey = Mid$(m_sKey, Len(p_sParentKey) + 2)
  552.         End If
  553.         
  554.         p_lRet = RegDeleteKey(p_lKey, p_sChildKey)
  555.         
  556.         If (p_lRet = ERROR_SUCCESS) Then
  557.             DeleteKey = True
  558.         End If
  559.         
  560.         RegCloseKey p_lKey
  561.     Else
  562.         Err.Raise ClassRoot, , "Unable to open registry key '" & p_sParentKey & "' for delete access."
  563.     End If
  564. End Function
  565.  
  566. Public Function DeleteTree(Optional ClassRoot, Optional Key) As Boolean
  567. Attribute DeleteTree.VB_Description = "Remove the specified registry key and all of its subkeys."
  568. 'Remove the specified registry key and all of its subkeys.
  569.     If (Not IsMissing(ClassRoot)) Then
  570.         m_eClassRoot = ClassRoot
  571.     End If
  572.     
  573.     If (Not IsMissing(Key)) Then
  574.         m_sKey = Key
  575.     End If
  576.     
  577.     Dim p_bHasSubKey    As Boolean
  578.     Dim p_sKeyArray()   As String
  579.     Dim p_sCurrentKey   As String
  580.     
  581.     p_sCurrentKey = m_sKey ' Set current key
  582.     
  583.     Do
  584.         If (p_bHasSubKey) Then
  585.             p_sCurrentKey = p_sCurrentKey & "\" & p_sKeyArray(0) 'Go deeper
  586.         Else
  587.             ' Check if current key is a subkey
  588.             If (StrComp(p_sCurrentKey, m_sKey) <> 0) Then
  589.                 p_sCurrentKey = GetParentKey(p_sCurrentKey)
  590.             End If
  591.         End If
  592.         
  593.         ' Ensure that the system still process other events
  594.         If (GetQueueStatus(QS_ALLEVENTS)) Then
  595.             DoEvents
  596.         End If
  597.         
  598.         DeleteSubKeys m_eClassRoot, p_sCurrentKey
  599.         
  600.         ' Determine and get if current key has any subkeys
  601.         p_bHasSubKey = Me.EnumerateKeys(p_sKeyArray, m_eClassRoot, p_sCurrentKey)
  602.         
  603.         If (p_sCurrentKey = m_sKey) And (Not p_bHasSubKey) Then
  604.             Exit Do ' This is where we get out the loop
  605.         End If
  606.     Loop ' Does it looks like an infinite loop? hehe...
  607.     
  608.     If (DeleteKey(m_eClassRoot, m_sKey)) Then ' Attempt to delete the main key
  609.         DeleteTree = True ' If successful, then so as this function...
  610.     End If
  611. End Function
  612.  
  613. Public Function EnumerateData( _
  614.         DataArray() As String, _
  615.         Optional ClassRoot, _
  616.         Optional Key) As Boolean
  617. 'Enumerate the list of valuenames found on a specified registry key.
  618.     If (Not IsMissing(ClassRoot)) Then
  619.         m_eClassRoot = ClassRoot
  620.     End If
  621.     
  622.     If (Not IsMissing(Key)) Then
  623.         m_sKey = Key
  624.     End If
  625.     
  626.     Dim p_lKey As Long
  627.     Dim p_lRet As Long
  628.     
  629.     If (m_bRemoteConnection) Then
  630.         m_eClassRoot = m_lRemoteKey
  631.     End If
  632.     
  633.     p_lRet = RegOpenKeyEx(m_eClassRoot, m_sKey, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, p_lKey)
  634.     
  635.     If (p_lRet = ERROR_SUCCESS) Then
  636.         Dim p_sBuffer       As String
  637.         Dim p_lDataCount    As Long
  638.         Dim p_lDataLen      As Long
  639.         Dim p_lIndex        As Long
  640.         Dim p_lMaxLen       As Long
  641.         
  642.         Dim FT As FILETIME
  643.         p_lRet = RegQueryInfoKey(p_lKey, "", 0&, REG_OPTION_RESERVED, 0&, 0&, 0&, p_lDataCount, p_lMaxLen, 0&, 0&, FT)
  644.         
  645.         If (p_lDataCount > 0) Then
  646.             ReDim DataArray(0 To (p_lDataCount - 1)) As String
  647.             
  648.             Do
  649.                 p_lDataLen = p_lMaxLen + 1
  650.                 p_sBuffer = String$(p_lDataLen, 0)
  651.                 p_lRet = RegEnumValue(p_lKey, p_lIndex, p_sBuffer, p_lDataLen, REG_OPTION_RESERVED, 0&, 0&, 0&)
  652.                 
  653.                 If (p_lRet = ERROR_SUCCESS) Then
  654.                     DataArray(p_lIndex) = Left$(p_sBuffer, p_lDataLen)
  655.                 End If
  656.                 
  657.                 p_lIndex = p_lIndex + 1
  658.             Loop While ((p_lRet = ERROR_SUCCESS)) And (p_lIndex < p_lDataCount)
  659.             
  660.             EnumerateData = True
  661.         End If
  662.         
  663.         RegCloseKey p_lKey
  664.     Else
  665.         Err.Raise ClassRoot, , "Unable to open registry key '" & m_sKey & "' for data query access."
  666.     End If
  667. End Function
  668.  
  669. Public Function EnumerateKeys( _
  670.         KeyArray() As String, _
  671.         Optional ClassRoot, _
  672.         Optional Key) As Boolean
  673. 'Enumerate the list of subkeys found on a specified registry key.
  674.     If (Not IsMissing(ClassRoot)) Then
  675.         m_eClassRoot = ClassRoot
  676.     End If
  677.     
  678.     If (Not IsMissing(Key)) Then
  679.         m_sKey = Key
  680.     End If
  681.     
  682.     Dim p_lKey As Long
  683.     Dim p_lRet As Long
  684.     
  685.     If (m_bRemoteConnection) Then
  686.         m_eClassRoot = m_lRemoteKey
  687.     End If
  688.     
  689.     p_lRet = RegOpenKeyEx(m_eClassRoot, m_sKey, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE + KEY_ENUMERATE_SUB_KEYS, p_lKey)
  690.     
  691.     If (p_lRet = ERROR_SUCCESS) Then
  692.         Dim p_lIndex    As Long
  693.         Dim p_lKeyCount As Long
  694.         Dim p_lMaxLen   As Long
  695.         Dim p_sBuffer   As String
  696.         
  697.         Dim FT As FILETIME
  698.         p_lRet = RegQueryInfoKey(p_lKey, "", 0&, REG_OPTION_RESERVED, p_lKeyCount, p_lMaxLen, 0&, 0&, 0&, 0&, 0&, FT)
  699.         
  700.         If (p_lKeyCount > 0) Then
  701.             ReDim KeyArray(0 To (p_lKeyCount - 1)) As String
  702.             p_lMaxLen = p_lMaxLen + 1 ' for the terminating null character
  703.             
  704.             Do
  705.                 p_sBuffer = String$(p_lMaxLen, 0)
  706.                 p_lRet = RegEnumKey(p_lKey, p_lIndex, p_sBuffer, p_lMaxLen)
  707.                 
  708.                 If (p_lRet = ERROR_SUCCESS) Then
  709.                     KeyArray(p_lIndex) = Left$(p_sBuffer, lstrlen(p_sBuffer))
  710.                 End If
  711.                 
  712.                 p_lIndex = p_lIndex + 1
  713.             Loop While ((p_lRet = ERROR_SUCCESS)) And (p_lIndex < p_lKeyCount)
  714.             
  715.             EnumerateKeys = True
  716.         End If
  717.         
  718.         RegCloseKey p_lKey
  719.     Else
  720.         Err.Raise ClassRoot, , "Unable to open registry key '" & Key & "' for key query access."
  721.     End If
  722. End Function
  723.  
  724. Public Sub Export( _
  725.         File As String, _
  726.         Optional Overwrite As Boolean, _
  727.         Optional ClassRoot, _
  728.         Optional Key)
  729. 'Attempt to export the contents of a registry key and all of its subkeys to a file.
  730.     If (Not Overwrite) Then
  731.         If (Len(Dir$(File))) Then
  732.             Exit Sub ' Do not overwrite existing file
  733.         End If
  734.     End If
  735.     
  736.     Dim p_sParam As String
  737.     
  738.     If (Not IsMissing(ClassRoot)) Then
  739.         p_sParam = ClassRoot
  740.     End If
  741.     
  742.     If (Not IsMissing(Key)) Then
  743.         m_sKey = Key
  744.     End If
  745.     
  746.     If (IsNumeric(p_sParam)) Then
  747.         Select Case ClassRoot
  748.             Case HKEY_CLASSES_ROOT
  749.                 p_sParam = "HKEY_CLASSES_ROOT"
  750.             Case HKEY_CURRENT_USER
  751.                 p_sParam = "HKEY_CURRENT_USER"
  752.             Case HKEY_LOCAL_MACHINE
  753.                 p_sParam = "HKEY_LOCAL_MACHINE"
  754.             Case HKEY_USERS
  755.                 p_sParam = "HKEY_USERS"
  756.             Case 0
  757.                 Err.Raise -1, , "Registry root class not accepted."
  758.                 Exit Sub
  759.             Case Else
  760.                 Err.Raise ClassRoot, , "Registry root class not supported."
  761.                 Exit Sub
  762.         End Select
  763.     End If
  764.     
  765.     p_sParam = p_sParam & "\" & m_sKey ' Build registry path
  766.     
  767.     ' Export via Windows« built-in Registry Editor
  768.     ShellExecute 0&, "", "regedit", "/e """ & File & """ " & p_sParam, "", vbHide
  769. End Sub
  770.  
  771. Public Function HasSubKey(Optional ClassRoot, Optional Key) As Boolean
  772. Attribute HasSubKey.VB_Description = "Returns a value to determine if the registry path supplied contains subkeys."
  773. 'Returns a value to determine if the registry path supplied contains subkeys.
  774.     If (Not IsMissing(ClassRoot)) Then
  775.         m_eClassRoot = ClassRoot
  776.     End If
  777.     
  778.     If (Not IsMissing(Key)) Then
  779.         m_sKey = Key
  780.     End If
  781.     
  782.     Dim p_lKey As Long
  783.     Dim p_lRet As Long
  784.     
  785.     If (m_bRemoteConnection) Then
  786.         m_eClassRoot = m_lRemoteKey
  787.     End If
  788.     
  789.     p_lRet = RegOpenKeyEx(m_eClassRoot, m_sKey, REG_OPTION_NON_VOLATILE, KEY_ENUMERATE_SUB_KEYS, p_lKey)
  790.     
  791.     If (p_lRet = ERROR_SUCCESS) Then
  792.         Dim p_sBuffer As String * MAX_CLASS_NAME
  793.         
  794.         p_lRet = RegEnumKey(p_lKey, 0&, p_sBuffer, MAX_CLASS_NAME) ' Attempt to get subkey
  795.         
  796.         If (p_lRet = ERROR_SUCCESS) Then
  797.             HasSubKey = True
  798.         End If
  799.         
  800.         RegCloseKey p_lKey
  801.     Else
  802.         Err.Raise ClassRoot, , "Unable to open registry key '" & m_sKey & "' for enumerate subkeys access."
  803.     End If
  804. End Function
  805.  
  806. Public Sub Import(ByVal File As String)
  807. Attribute Import.VB_Description = "Attempt to import a valid registry file to the registry."
  808. 'Attempt to import a valid registry file to the registry.
  809.     File = Trim$(File)
  810.     
  811.     If (Len(Dir$(File))) Then
  812.         ShellExecute 0&, "", "regedit", "/s """ & File & """", App.Path, vbHide
  813.     Else
  814.         Err.Raise 53 ' File not found
  815.     End If
  816. End Sub
  817.  
  818. Public Function KeyExists(Optional ClassRoot, Optional Key) As Boolean
  819. Attribute KeyExists.VB_Description = "Returns/sets a value to determine if a key exists on the registry."
  820. 'Returns a value to determine if a key exists on the registry.
  821.     If (Not IsMissing(ClassRoot)) Then
  822.         m_eClassRoot = ClassRoot
  823.     End If
  824.     
  825.     If (Not IsMissing(Key)) Then
  826.         m_sKey = Key
  827.     End If
  828.     
  829.     Dim p_lKey As Long
  830.     Dim p_lRet As Long
  831.     
  832.     If (m_bRemoteConnection) Then
  833.         m_eClassRoot = m_lRemoteKey
  834.     End If
  835.     
  836.     p_lRet = RegOpenKeyEx(m_eClassRoot, m_sKey, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, p_lKey)
  837.     
  838.     If (p_lRet = ERROR_SUCCESS) Or (p_lRet = ERROR_ACCESS_DENIED) Then
  839.         KeyExists = True
  840.         RegCloseKey p_lKey
  841.     End If
  842. End Function
  843.  
  844. Public Function RemoteConnect(Optional MachineName, Optional ClassRoot) As Boolean
  845. Attribute RemoteConnect.VB_Description = "Establish a remote registry connection."
  846. 'Establish a remote registry connection.
  847.     If (Not IsMissing(MachineName)) Then
  848.         m_sMachineName = MachineName
  849.     End If
  850.     
  851.     If (Not IsMissing(ClassRoot)) Then
  852.         m_eClassRoot = ClassRoot
  853.     End If
  854.     
  855.     Dim p_lKey As Long
  856.     Dim p_lRet As Long
  857.     
  858.     p_lRet = RegConnectRegistry(m_sMachineName, m_eClassRoot, p_lKey)
  859.     
  860.     If (p_lRet = ERROR_SUCCESS) Then
  861.         m_lRemoteKey = p_lKey
  862.         m_eRemoteClassRoot = m_eClassRoot
  863.         m_bRemoteConnection = True
  864.         RemoteConnect = True
  865.     Else
  866.         Err.Raise ClassRoot, , "Unable to establish remote registry connection: '" & m_sMachineName & "'"
  867.     End If
  868. End Function
  869.  
  870. Public Function RemoteDisconnect() As Boolean
  871. Attribute RemoteDisconnect.VB_Description = "Disconnect from remote registry connection."
  872. 'Disconnect from remote registry connection.
  873.     If (m_bRemoteConnection) Then
  874.         Dim p_lKey As Long
  875.         Dim p_lRet As Long
  876.         
  877.         p_lRet = RegCloseKey(m_lRemoteKey)
  878.         p_lRet = RegConnectRegistry("", m_eRemoteClassRoot, p_lKey) ' Connect from local system
  879.         
  880.         If (p_lRet = ERROR_SUCCESS) Then
  881.             RegCloseKey p_lKey ' Then close registry handle
  882.             
  883.             m_lRemoteKey = 0
  884.             m_eRemoteClassRoot = 0
  885.             m_bRemoteConnection = False
  886.             RemoteDisconnect = True
  887.         Else
  888.             Err.Raise m_eRemoteClassRoot, , "Unable to disconnect from remote registry connection."
  889.         End If
  890.     End If
  891. End Function
  892.  
  893. Public Function ValueNameExists( _
  894.         Optional ClassRoot, _
  895.         Optional Key, _
  896.         Optional ValueName) As Boolean
  897. 'Returns a value to determine if the specified valuename exists in a particular key.
  898.     If (Not IsMissing(ClassRoot)) Then
  899.         m_eClassRoot = ClassRoot
  900.     End If
  901.     
  902.     If (Not IsMissing(Key)) Then
  903.         m_sKey = Key
  904.     End If
  905.     
  906.     If (Not IsMissing(ValueName)) Then
  907.         m_sValueName = ValueName
  908.     End If
  909.     
  910.     Dim p_lKey As Long
  911.     Dim p_lRet As Long
  912.     
  913.     If (m_bRemoteConnection) Then
  914.         m_eClassRoot = m_lRemoteKey
  915.     End If
  916.     
  917.     p_lRet = RegOpenKeyEx(m_eClassRoot, m_sKey, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, p_lKey)
  918.     
  919.     If (p_lRet = ERROR_SUCCESS) Then
  920.         p_lRet = RegQueryValueExString(p_lKey, m_sValueName, REG_OPTION_RESERVED, 0&, "", 0&)
  921.         
  922.         If (p_lRet = ERROR_SUCCESS) Or (p_lRet = ERROR_MORE_DATA) Then
  923.             ValueNameExists = True
  924.         End If
  925.         
  926.         RegCloseKey p_lKey
  927.     Else
  928.         Err.Raise ClassRoot, , "Unable to open registry key '" & m_sKey & "' for key query access."
  929.     End If
  930. End Function
  931.  
  932. ' //-- Private procedures --//
  933.  
  934. Private Sub DeleteSubKeys(ByVal ClassRoot As String, Key As String)
  935. ' Deletes only subkeys with no child keys
  936.     Dim p_lCtr          As Long
  937.     Dim p_sKeyArray()   As String
  938.     
  939.     If (EnumerateKeys(p_sKeyArray, ClassRoot, Key)) Then
  940.         For p_lCtr = LBound(p_sKeyArray) To UBound(p_sKeyArray)
  941.             ' Attempt to delete every subkey found
  942.             DeleteKey ClassRoot, Key & "\" & p_sKeyArray(p_lCtr)
  943.         Next
  944.     End If
  945. End Sub
  946.  
  947. Private Function ExpandEnvironmentString(Value As String) As String
  948.     Dim p_lLen      As Long
  949.     Dim p_sBuffer   As String
  950.     
  951.     ' Get length of expanded string
  952.     p_sBuffer = ""
  953.     p_lLen = ExpandEnvironmentStrings(Value, p_sBuffer, p_lLen)
  954.     
  955.     ' Expand string
  956.     p_sBuffer = String$(p_lLen, 0)
  957.     p_lLen = ExpandEnvironmentStrings(Value, p_sBuffer, p_lLen)
  958.     
  959.     If (p_lLen > 0) Then
  960.         ' Without the terminating null character
  961.         ExpandEnvironmentString = Left$(p_sBuffer, p_lLen - 1)
  962.     End If
  963. End Function
  964.  
  965. Private Function GetParentKey(ByVal Value As String) As String
  966.     Dim i As Long
  967.     i = InStrRev(Value, "\")
  968.     
  969.     If (i > 0) Then
  970.         GetParentKey = Left$(Value, i - 1) ' Get parent key
  971.     End If
  972. End Function
  973.  
  974. Private Function GetBigEndianValue(ByVal Value As Long) As Long
  975.     CopyMemory ByVal VarPtr(GetBigEndianValue) + 3, Value, 1
  976.     CopyMemory ByVal VarPtr(GetBigEndianValue) + 2, ByVal VarPtr(Value) + 1, 1
  977.     CopyMemory ByVal VarPtr(GetBigEndianValue) + 1, ByVal VarPtr(Value) + 2, 1
  978.     CopyMemory GetBigEndianValue, ByVal VarPtr(Value) + 3, 1
  979. End Function
  980.  
  981. Private Sub ValidateMachineName(Value As String)
  982.     If (Len(Value)) Then
  983.         If (InStr(1, Value, "\\") = 0) Then
  984.             Value = "\\" & Value ' This would be enough for now
  985.         End If
  986.     End If
  987. End Sub
  988.  
  989. ' //-- Class Procedure --//
  990.  
  991. Private Sub Class_Initialize()
  992.     ' Unless these properties are set, these would be their default values
  993.     m_eClassRoot = HKEY_CURRENT_USER
  994.     m_eDataType = REG_SZ
  995.     
  996.     ' This is the required path format in writing software settings in the registry
  997.     m_sKey = "Software\" & App.CompanyName & "\" & App.ProductName
  998. End Sub
  999.  
  1000. ' Created by Noel A. Dacara | Copyright ⌐ 2003-2005 Davao City, Philippines
  1001.